/**
 * 
 */
package org.istt.export;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.istt.domain.File;
import org.istt.domain.WorkflowProcess;

/**
 * @author Ndtho
 *
 */
public class ProcessingReportCreator extends BaseReport{
	String address = "$Address$";
	String building = "$Building$";
	String category = "$Category$";
	String contact = "$Contact$";
	String contactFax = "$Contact_Fax$";
	String contactPhone = "$Contact_Phone$";
	String contractor = "$Contractor$";
	String index = "$Index$";
	String location = "$Location$";
	
	String no = "$List_No$";
	private String organization = "$Organization$";
	private String organizationFax = "$OrganizationFax$";

	private String organizationTel = "$OrganizationTel$";
	// Ngay hen tra ho so
	private String outputDate = "$Output_Date$";
	
	String serial = "$Serial$";
	String stepName = "$List_Step_Name$";
	String strAccept = "$List_Accept$";
	String strComment = "$List_Comment$";
	String strDone = "$List_Done$";
	
	String strReject = "$List_Reject$";
	
	String strSignature = "$List_Signature$";

	String strTime = "$List_Time$";

	String strTotalTime = "$TotalTime$";

	String subCategory = "$Sub_Category$";

	String submiter = "$Submiter$";

	String today = "$Today$";
	
	String totalTime = "$Total_Time$";

	private void createRow(XWPFTable table, List<Object[]> fileProcessVoucher, ArrayList<String> lstElement,File f){
		Set<WorkflowProcess> workflowProcesses = f.getCategory().getWorkflow().getWorkflowProcesses();
		// Call create row
    	
    	int cellNumberRequireTime = 0;
    	int cellNumberDoneTime = 0;
    	int cellNumberTotal = 0;
    	int counter = 1;
    	
    	try {
    		table.removeRow(2);
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	
    	Float totalDoneTime = 0f;
	    Float totalRequiredTime = 0f;
		 for (int i = 1; i <= workflowProcesses.size(); i++) {
		    	for (WorkflowProcess w : workflowProcesses) {
		    		if (w.getPosition().equals(i)) {
			    		Float requiredTime = new Float(w.getProcessTime());
			    		totalRequiredTime += requiredTime;
			    		XWPFTableRow content_row = table.createRow();
			    		content_row.createCell();
			    		content_row.createCell();
			    		
			    		int cellNumber = 0;
			    		for (Iterator<String> iterator = lstElement.iterator(); iterator.hasNext();) {
							String strKey = (String) iterator.next();
							
							// So tt
							if(strKey.contains(no)){
			        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
			        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
			            		setTextFormat(run, counter + "", FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
			        		}
							
							// Ten buoc xu ly
			        		if(strKey.contains(stepName)){
			        			cellNumberTotal = cellNumber;
			        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
			        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), LEFT_ALIGN, SPACING_0, SPACING_06);
			        	        setTextFormat(run, w.getProcessStatus().getDescription(), FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
			        		}
			        		
			        		// Thoi gian yeu cau xu ly
			        		if(strKey.contains(strTime)){
			        			cellNumberRequireTime = cellNumber;
			        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
			        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
			        			setTextFormat(run, w.getProcessTime() + "", FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
			        		}
			        		
			        		for (int j = 0; j < fileProcessVoucher.size(); j++) {
				    			if (i==j+1) {
				    				//Fixed by Thond.2012.03.07
				    				Float doneTime = null;
				    				if(fileProcessVoucher.get(j)[0]!=null){
				    					doneTime = new Float(fileProcessVoucher.get(j)[0] + "");
				    				}
					    	    	
				    				// Thoi gian thuc te
					    	    	if(strKey.contains(strDone)){
					    	    		cellNumberDoneTime = cellNumber;
					    	    		
					        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
					        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), LEFT_ALIGN, SPACING_0, SPACING_06);
					        	        if(doneTime != null){
						                	totalDoneTime += doneTime;
						                	setTextFormat(run, doneTime + "", FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
						                }
					        		}
					                
					                // Nhan xet khi khong dong y
					                if(strKey.contains(strComment)){
					        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
					        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), LEFT_ALIGN, SPACING_0, SPACING_06);
					        	        setTextFormat(run, StringUtils.trim((String)fileProcessVoucher.get(j)[2]), FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
					        		}
					    	    	
					                // Ngay ky/chu ky
					    	    	if(strKey.contains(strSignature)){
					        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
					        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), LEFT_ALIGN, SPACING_0, SPACING_06);
					        			
					        			if(StringUtils.trim((String)fileProcessVoucher.get(j)[1]) != null)
					        				setTextFormat(run, StringUtils.trim((String)fileProcessVoucher.get(j)[1]) + "\n" + StringUtils.trim((String)fileProcessVoucher.get(j)[3]), FONT_SIZE_11, false, false, FONT_TIMES_NEW_ROMAN);
						    	    	else
						    	    		setTextFormat(run, "(Ch\u01B0a k\u00FD)"+ "\n" +StringUtils.trim((String)fileProcessVoucher.get(j)[3]), FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
					        		}
					    	    	
					    	    	if(fileProcessVoucher.get(j)[7]!=null){
					                	if (fileProcessVoucher.get(j)[7].equals(true)) {
					                		if(strKey.contains(strAccept)){
							        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
							        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
							        	        setTextFormat(run, "X", FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
							        		}
					                	}
					                	if (fileProcessVoucher.get(j)[7].equals(false)) {
					                		if(strKey.contains(strReject)){
							        			XWPFRun run = content_row.getCell(cellNumber).getParagraphs().get(0).createRun();
							        			setAlignment(content_row.getCell(cellNumber).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
							        	        setTextFormat(run, "X", FONT_SIZE_10, false, false, FONT_TIMES_NEW_ROMAN);
							        		}
					                	}		                
					                }
				    			}
				    		}
			        		
							cellNumber++;
						}
		        		
		    	        counter++;
		    	        
		    		}
		    	}
		    }
		 
		 // Footer of table
		 	XWPFTableRow row2 = table.createRow();
	        row2.createCell();
	        row2.createCell();
	        
	        XWPFRun r4 = row2.getCell(cellNumberTotal).getParagraphs().get(0).createRun(); 
	        setAlignment(row2.getCell(cellNumberTotal).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
	        setTextFormat(r4, "T\u1ED5ng c\u1ED9ng", FONT_SIZE_10, true, false, FONT_TIMES_NEW_ROMAN);
	        
	        //total required time
	        XWPFRun r2 = row2.getCell(cellNumberRequireTime).getParagraphs().get(0).createRun(); 
	        setAlignment(row2.getCell(cellNumberRequireTime).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
	        setTextFormat(r2, totalRequiredTime + "", FONT_SIZE_10, true, false, FONT_TIMES_NEW_ROMAN);

	  	    //total done time
	    	XWPFRun r1 = row2.getCell(cellNumberDoneTime).getParagraphs().get(0).createRun();
	    	setAlignment(row2.getCell(cellNumberDoneTime).getParagraphs().get(0), CENTER_ALIGN, SPACING_0, SPACING_06);
	        setTextFormat(r1, Round(totalDoneTime,1) + "", FONT_SIZE_10, true, false, FONT_TIMES_NEW_ROMAN);
	        totalTime = totalRequiredTime.toString();
	}

	public String getOrganization() {
		return organization;
	}
	public String getOrganizationFax() {
		return organizationFax;
	}
	public String getOrganizationTel() {
		return organizationTel;
	}
	
	public void readTable(XWPFTable table, List<Object[]> fileProcessVoucher, File f){
		List<XWPFTableRow> lstRows = table.getRows();
		boolean isIterator = false;
		boolean isTotal = false;
		ArrayList<String> lstElement = new ArrayList<String>();
		
        for (Iterator<XWPFTableRow> iterator = lstRows.iterator(); iterator.hasNext();) {
			XWPFTableRow xwpfTableRow = (XWPFTableRow) iterator.next();
			
			if(isIterator) continue;
			
			List<XWPFTableCell> lstCells = xwpfTableRow.getTableCells();
			for (Iterator<XWPFTableCell> iterator2 = lstCells.iterator(); iterator2.hasNext();) {
				XWPFTableCell xwpfTableCell = (XWPFTableCell) iterator2.next();
				List<XWPFParagraph> lstParagraph = xwpfTableCell.getParagraphs();
				
				for (Iterator<XWPFParagraph> iterator3 = lstParagraph.iterator(); iterator3.hasNext();) {
					XWPFParagraph xwpfParagraph = (XWPFParagraph) iterator3.next();
					
					System.out.println(" -- "+xwpfParagraph.getParagraphText());
					
					String strText = xwpfParagraph.getParagraphText();
					
					if(strText.contains("$List")){
						
						lstElement.add(strText);
						
						isIterator = true;
						
					}else if(strText.contains(strTotalTime)){
						isTotal = true;
					}else{
						
						
						replaceString(xwpfParagraph,serial,f.getNumber().toString());
						replaceString(xwpfParagraph,index,f.getId());
						
						DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
						Date dateToday = new Date();
						String strDate =  dateFormat.format(dateToday);
						String strToday = " ng\u00E0y "+strDate.substring(0, 2)+" th\u00E1ng "+strDate.substring(3, 5)+" n\u0103m "+strDate.substring(6, 10) ;

						replaceString(xwpfParagraph,today,strToday);
						replaceString(xwpfParagraph,category,f.getCategory().getCategoryName());
						replaceString(xwpfParagraph,subCategory,getSubCategoryName(f.getSubCategory()));
						replaceString(xwpfParagraph,submiter,f.getSubmitter());
						replaceString(xwpfParagraph,address,f.getAddress());
						replaceString(xwpfParagraph,contact,f.getContactName());
						replaceString(xwpfParagraph,contactPhone,f.getContactPhone());
						replaceString(xwpfParagraph,this.organization,f.getOrganization());
						replaceString(xwpfParagraph,this.organizationTel,f.getOrgPhone());
						replaceString(xwpfParagraph,this.organizationFax,f.getOrgFax());
						
						String dateStr = f.getOutputDate().toString();
						replaceString(xwpfParagraph,this.outputDate,"Ng\u00E0y "
								+ dateStr.substring(8, 10)
								+ " th\u00E1ng "
								+ dateStr.substring(5, 7)
								+ " n\u0103m "
								+ dateStr.substring(0, 4)
								+ ", "
								+ f.getOutputDate().dayOfWeek().getAsText(new Locale("vi")));

						replaceString(xwpfParagraph,contactFax,f.getContactFax());
						replaceString(xwpfParagraph,location,f.getLocation());
						replaceString(xwpfParagraph,building,f.getConstruct());
						replaceString(xwpfParagraph,contractor,f.getOversea());
					}
				}
			}
		}
        
        if(isIterator){
        	createRow(table, fileProcessVoucher, lstElement, f);
        }
        
        if(isTotal){
        	updateTotalTime(table,totalTime);
        }
	}
	
	private void replaceString(XWPFParagraph xwpfParagraph, String reglex, String replacement){
		if(xwpfParagraph.getParagraphText().contains(reglex)){
			List<XWPFRun> runs = xwpfParagraph.getRuns();
			for (Iterator<XWPFRun> iterator4 = runs.iterator(); iterator4.hasNext();) {
				XWPFRun xwpfRun = (XWPFRun) iterator4.next();
				String textOfRun = xwpfRun.getText(0);
				if(textOfRun.contains(reglex))
					xwpfRun.setText(replacement,0);
				
			}
		}
	}
	
	public void setOrganization(String organization) {
		this.organization = organization;
	}
	
	public void setOrganizationFax(String organizationFax) {
		this.organizationFax = organizationFax;
	}
	
	public void setOrganizationTel(String organizationTel) {
		this.organizationTel = organizationTel;
	}
	
	public InputStream toMSWord(InputStream docFile,File f, List<Object[]> fileProcessVoucher) throws IOException {
		
	    XWPFDocument docx = new XWPFDocument(docFile);
	    Iterator<XWPFTable> range=docx.getTablesIterator();
	    while(range.hasNext()){
	    
	    	XWPFTable tableHeader=range.next();
	    	
	    	readTable(tableHeader,fileProcessVoucher, f);
	    }
	    
	    //write to word file
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    docx.write(baos);
	    
	    return new ByteArrayInputStream(baos.toByteArray());
	}
	
	private void updateTotalTime(XWPFTable table, String totalTime){
		List<XWPFTableRow> lstRows = table.getRows();
		for (Iterator<XWPFTableRow> iterator = lstRows.iterator(); iterator.hasNext();) {
			XWPFTableRow xwpfTableRow = (XWPFTableRow) iterator.next();
			
			List<XWPFTableCell> lstCells = xwpfTableRow.getTableCells();
			for (Iterator<XWPFTableCell> iterator2 = lstCells.iterator(); iterator2.hasNext();) {
				XWPFTableCell xwpfTableCell = (XWPFTableCell) iterator2.next();
				List<XWPFParagraph> lstParagraph = xwpfTableCell.getParagraphs();
				
				for (Iterator<XWPFParagraph> iterator3 = lstParagraph.iterator(); iterator3.hasNext();) {
					XWPFParagraph xwpfParagraph = (XWPFParagraph) iterator3.next();
					
					String strText = xwpfParagraph.getParagraphText();
					
					if(strText.contains(strTotalTime)){
						replaceString(xwpfParagraph,strTotalTime,totalTime);
					}
				}
			}
		}
	}
}
